using System;
using System.Collections.Generic;
using Clandestine.Engines.Field;

namespace Shlick.LayerModel
{	
	internal class LevelItem : Item
	{
		public Level Level { get; private set; }
		
		private LevelItem(Level item, MapDocument mapDocument, LayerTreeMode mode) : base(item, mapDocument, mode)
		{
			this.Level = item;
		}
		
		public static LevelItem Get(Level item, MapDocument mapDocument, LayerTreeMode mode)
		{
			if (cachedItems.ContainsKey(mode) && cachedItems[mode].ContainsKey(item))
				return (LevelItem)cachedItems[mode][item];
			else
				return new LevelItem(item, mapDocument, mode);
		} 
		
		public override int Row()
		{
			List<Level> levels = ((MapItem)this.Parent()).Map.Levels;
			for (int i=0; i < levels.Count; i++)
				if (levels[i] == this.Level)
					return i;
			throw new Exception();
		}
		
		public override Item Child(int row)
		{
			// If .Mode is Map, return Sky/Floor; For .Level return null; .Object should never happen
			if (this.Mode == LayerTreeMode.Map)
				switch (row)
				{
					case 0: // Sky
						return LayerGroupItem.Get(this.Level.SkyLayers, this.MapDocument, this.Mode);
					case 1: // Object
						return ObjectListItem.Get(this.Level.Objects, this.MapDocument, this.Mode);
					case 2: // Floor
						return LayerGroupItem.Get(this.Level.FloorLayers, this.MapDocument, this.Mode);
				}
			else if (this.Mode == LayerTreeMode.Level)
				return null;
			throw new Exception();
		}
		
		public override Item Parent()
		{
			return MapItem.Get(this.Level.Map, this.MapDocument, this.Mode);
		}
		
		public override int ChildrenCount()
		{
			// In .Map we just have Sky/Objects/Floor, in .Level we have none
			// LevelItem is never used in .Object mode.
			if (this.Mode == LayerTreeMode.Map)
				return 3; 
			else if (this.Mode == LayerTreeMode.Level)
				return 0;
			throw new Exception();
		}
		
		public override string GetData()
		{
			 return String.Format("Level");
		}
		
		public override int? GetDepth()
		{
			return this.Level.Depth;
		}
		
		public override string GetName()
		{
			return string.Empty;
		}
		
		public override bool? IsVisible()
		{
			 return this.Level.Visible;
		}
		
		public override bool SetVisible(bool visible)
		{
			this.Level.Visible = visible;
			return true;
		}
	}
}